home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / ImageWriter / ChooserSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  9.0 KB  |  316 lines  |  [TEXT/MPS ]

  1. /*
  2.     ChooserSupport.c - C code for PACK and LDEF resources used by the Chooser.
  3.     
  4.     Copyright © 1992-1994 Apple Computer, Inc.
  5.     All rights reserved.
  6.  
  7.     12/20/93        dmh                Sync'd with the shipping 1.0b3 GX driver.
  8.      8/26/94        dmh                Sync'd with the shipping 1.0.1 GX driver.
  9.      8/26/94        dmh                Universalized code.
  10. */
  11.  
  12. #include <Types.h>
  13. #include <QuickDraw.h>
  14. #include <Fonts.h>
  15. #include <Lists.h>
  16. #include <Devices.h>
  17. #include <Resources.h>
  18. #include <Script.h>
  19. #include <ToolUtils.h>
  20. #include <LowMem.h>
  21.  
  22. #include "graphics routines.h"
  23. #include <PrintingDrivers.h>
  24.  
  25. // ------------------------------------------------------------------------
  26. // INTERNAL DEFINES
  27. // ------------------------------------------------------------------------
  28. // Chooser initialize message selector
  29. #define initializeMsg    11
  30.  
  31. // Icon Suite support
  32. #define ttNone        0x0000
  33. #define ttDisabled    0x0001
  34. #define    ttOffline    0x0002
  35. #define ttOpen        0x0003
  36. #define ttSelected     0x4000
  37. #define ttSelectedDisabled    (ttSelected + ttDisabled)
  38. #define ttSelectedOffline    (ttSelected + ttOffline)
  39. #define ttSelectedOpen        (ttSelected + ttOpen)
  40.  
  41. #define ttLabel0    0x0000
  42. #define ttLabel1    0x0100
  43. #define ttLabel2    0x0200
  44. #define ttLabel3    0x0300
  45. #define ttLabel4    0x0400
  46. #define ttLabel5    0x0500
  47. #define ttLabel6    0x0600
  48. #define ttLabel7    0x0700
  49. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  50.     = {0x303C, 0x0603, 0xABC9};
  51.  
  52. // Copy of the DrawText trap
  53. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  54.     = 0xA885; 
  55.  
  56. // ------------------------------------------------------------------------
  57. // MAIN CODE FOR PACK
  58. // ------------------------------------------------------------------------
  59. pascal OSErr Device(short message, short caller, StringPtr objName, 
  60.                     StringPtr zoneName, ListHandle theList, long p2)
  61. {
  62.     
  63.     OSErr            anErr = noErr;
  64.     extern Str31     gDriverName;
  65.     StringPtr        pDriverName = &gDriverName;
  66.     extern gxJob    gJob;                        // Declared in our .a file.
  67.     gxJob            *pJob = &gJob;
  68.  
  69.     if (message == initializeMsg)    // InitializeMsg--start up GX
  70.     {
  71.         FCBPBRec    pb;
  72.  
  73.     /*
  74.         Get the name of our driver for GXHandleChooserMessage.
  75.         (The user may have renamed us.)
  76.     */
  77.         pb.ioCompletion     = nil;
  78.         pb.ioNamePtr         = pDriverName;
  79.         pb.ioVRefNum         = 0;
  80.         pb.ioRefNum         = CurResFile();
  81.         pb.ioFCBIndx         = 0;
  82.         anErr = PBGetFCBInfo(&pb, false);
  83.  
  84.     /*
  85.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  86.         happen until we pass GXHandleChooserMessage an initializeMsg.
  87.     */
  88.         *pJob = nil;
  89.  
  90.     /*
  91.         We need to initialize GX printing so that we can call
  92.         GXHandleChooserMessage.  Since printing requires a graphics
  93.         client, call GXEnterGraphics first.  If there are errors,
  94.         (for example, due to memory limitations), post an alert.
  95.     */
  96.         if (anErr == noErr)
  97.         {
  98.             GXEnterGraphics();
  99.             anErr = GXGetGraphicsError(nil);
  100.             if (anErr == noErr)
  101.             {
  102.                 anErr = GXInitPrinting();
  103.                 if (anErr != noErr)
  104.                     GXExitGraphics();
  105.             }
  106.                 
  107.             if (anErr != noErr)
  108.                 StopAlert(-4095, nil);
  109.         }
  110.     }
  111.  
  112. /*
  113.     If the Chooser hasn't created a job yet, do nothing unless we were
  114.     sent an initializeMsg.  In its default implementation of
  115.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  116.     driver when it receives an initializeMsg.  It will store a reference
  117.     to it in our pJob pointer.
  118.     
  119.     For all other messages, if a job has been created, call
  120.     GXHandleChooserMessage to handle things.
  121. */
  122.     if (anErr == noErr)
  123.     {
  124.         if ((*pJob != nil) || (message == initializeMsg))
  125.         {
  126.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  127.     
  128.         /*
  129.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  130.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  131.             created earlier when GXHandleChooserMessage was passed
  132.             initializeMsg, so we just need to call GXExitPrinting and
  133.             GXExitGraphics to clean up.
  134.             
  135.             Note that we must test the p2 parameter, because the Chooser
  136.             can also send terminateMsg when it wants to empty the device
  137.             list, but not dispose of us.  For example, this will happen
  138.             when the user turns off AppleTalk in the Chooser.
  139.         */
  140.             if ((message == terminateMsg) && (p2 == terminateMsg))
  141.             {
  142.                 GXExitPrinting();
  143.                 GXExitGraphics();
  144.             }
  145.         }
  146.     }
  147.         
  148.     return(anErr);
  149.     
  150. } // Device
  151.  
  152.  
  153.  
  154. // ------------------------------------------------------------------------
  155. // ENTRY POINT FOR LDEF
  156. // ------------------------------------------------------------------------
  157.  
  158. pascal void LDEF(
  159.     short         message,        // What operation to perform on list
  160.     Boolean     select,            // Is this cell to be selected or not?
  161.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  162.     Cell        theCell,        // Which cell this is
  163.     short        dataOffset,        // Offset into data for this cell
  164.     short        dataLen,        // Length of data for this cell
  165.     ListHandle    theList)        // The list to act upon
  166. /*
  167.     An LDEF that works in two modes:
  168.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  169.           then the LDEF is just a basic text LDEF
  170.         - otherwise, it assumes the data is part of a PortListRec, which is
  171.           a structure for icons with text underneath
  172. */
  173.  
  174. {
  175. #pragma unused (theCell, dataLen)
  176.  
  177.     gxPortListRec        theCellContents;
  178.     Rect                iconRect;
  179.     unsigned char        hiliteMode;
  180.     
  181.     switch (message)
  182.         {
  183.         case lDrawMsg:
  184.         case lHiliteMsg:
  185.         
  186.             // save the data to avoid locking things down
  187.             if (dataLen > sizeof(theCellContents) )
  188.                 dataLen = sizeof(theCellContents);
  189.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  190.             
  191.             // draw the cell as an icon, but only if we see our magic marker at the front
  192.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  193.                 {
  194.                 // center the icon rect on the list with a top margin of 10 pixels
  195.                 iconRect.top = theRect->top + 10;
  196.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  197.                 iconRect.bottom = iconRect.top + 32;
  198.                 iconRect.right = iconRect.left + 32;
  199.                 
  200.                 
  201.                 // draw the icon
  202.                 if (theCellContents.iconSuiteHandle != nil)
  203.                     PlotIconSuite(&iconRect,
  204.                             ttNone, (select) ? ttSelected: ttNone,
  205.                             theCellContents.iconSuiteHandle);
  206.                             
  207.                 // Get the general area under the icon in which to draw the label
  208.                 iconRect.left = theRect->left + 2;
  209.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  210.                 iconRect.top = iconRect.bottom + 2;
  211.                 iconRect.bottom = theRect->bottom;
  212.     
  213.                 // use a nice small font for the label            
  214.                 TextFont(applFont);
  215.                 TextSize(9);
  216.                 
  217.                     {
  218.                     short        labelWidth;
  219.                     short        rectWidth;
  220.                     short        labelHeight;
  221.                     FontInfo    theInfo;
  222.                 
  223.                     // Get rid of any text that was there before
  224.                     EraseRect(&iconRect);
  225.                     iconRect.top += 2;
  226.                     
  227.                     // compute the height of the label                    
  228.                     GetFontInfo(&theInfo);
  229.                     labelHeight = theInfo.ascent + theInfo.leading;
  230.                     
  231.                     // compute where to draw the text
  232.                     iconRect.bottom = iconRect.top + labelHeight;
  233.                     rectWidth = iconRect.right-iconRect.left;
  234.                     
  235.                     // truncate the string to fit within the box
  236.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  237.                     
  238.                     // compute the new width of the string
  239.                     labelWidth = StringWidth(theCellContents.iconName);
  240.                     
  241.                     // center the string, draw it
  242.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  243.                     MoveTo(iconRect.left, iconRect.bottom);
  244.                     DrawString(theCellContents.iconName);
  245.                     
  246.                     if (select)
  247.                         {
  248.                         // compute right and lower edge of box bounding the text we just drew
  249.                         iconRect.right = iconRect.left + labelWidth;
  250.                         iconRect.bottom += theInfo.descent;
  251.                         
  252.                         // outset it, and invert it to select it
  253.                         InsetRect(&iconRect, -1, -1);
  254.                         hiliteMode = LMGetHiliteMode();
  255.                         BitClr(&hiliteMode, pHiliteBit);
  256.                         LMSetHiliteMode(hiliteMode);
  257.                         InvertRect(&iconRect);
  258.                         }
  259.                     }
  260.                     
  261.                 TextFont(applFont);
  262.                 TextSize(0);
  263.                 }
  264.             else
  265.                 {
  266.                 // how boring!  It's only text
  267.                 FontInfo    theInfo;
  268.                 Rect        ourRect;
  269.                 short        cellWidth;
  270.                 
  271.                 // add a margin to the rectangle
  272.                 ourRect = *theRect;
  273.                 ourRect.left += 4;
  274.                 --ourRect.right;
  275.                 cellWidth = ourRect.right - ourRect.left;
  276.                 
  277.                 // erase the rectangle
  278.                 GetFontInfo(&theInfo);
  279.                 EraseRect(theRect);
  280.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  281.                 
  282.                 // hey, you can't park that string here -- it's too big!
  283.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  284.                     {
  285.                     // condense the text first
  286.                     TextFace(condense);
  287.                     
  288.                     // then truncate afterwards
  289.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  290.                     }
  291.                     
  292.                 // those darn other languages!
  293.                 if (GetSysJust() == teJustRight)
  294.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  295.                     
  296.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  297.                 
  298.                 // if selected, invert it
  299.                 if (select)
  300.                     {
  301.                     hiliteMode = LMGetHiliteMode();
  302.                     BitClr(&hiliteMode, pHiliteBit);
  303.                     LMSetHiliteMode(hiliteMode);
  304.                     InvertRect(theRect);
  305.                     }
  306.                     
  307.                 // normal text again
  308.                 TextFace(normal);
  309.                 }
  310.                 
  311.             break;
  312.             
  313.         } // switch
  314.         
  315. } // LDEF
  316.